import { Logger } from "./Logger";

export default class HttpUtil {


    public static instance: HttpUtil = new HttpUtil();

    //example
    // HttpClient.instance.request("http://localhost:8080/haohttp/test", ()=>{
    //     console.log("http 请求 end=============");
    // }, {"nickName":"jhao", "hh":1, "id":9527});

    public static methodTypeOption: any = {
        GET: "GET",
        POST: "POST"
    }

    private methodType: string = "GET";

    private responseType: XMLHttpRequestResponseType = "json";

    private xhr: XMLHttpRequest;

    private myRequestHeader: Map<string, string> = new Map<string, string>();

    private hadSetContentType: boolean = false;
    private contentType: string = "";

    constructor() {
        this.xhr = new XMLHttpRequest();
    }

        // http://localhost:3000/m/productlist.html?search=%E9%9E%8B&price=1&num=2
    // 根据url中参数名获取值
    // ?search=%E9%9E%8B&price=1&num=2 参数
    // 参数名 = search  参数值 = 鞋
    // 参数名 = price  参数值 = 1
    // 参数名 = num  参数值 = 2
    public static getQueryString(name: string) {
        // console.log(location);
        // console.log(location.search);
        // 1. 获取整个url参数的值的字符串 去掉第一个字符串 按照&分割成一个数组
        let urlParams: string[] = location.search.substr(1).split('&');
        for (let i = 0; i < urlParams.length; i++) {
            // search=%E9%9E%8B  =前面参数名 以=分割 如果等号前面的和参数名一样 返回=号后面的参数的值
            if (name == urlParams[i].split('=')[0]) {
                // 返回当前参数的值 同时转码
                return decodeURIComponent(urlParams[i].split('=')[1]);
            }
        }
    }


    // --GET  or  POST
    public setMethod(method: string = HttpUtil.methodTypeOption.POST) {
        this.methodType = method;
    }

    public setParams(paramsObj: object): string {
        let resParams = "";
        let nowIndex = 1;
        for (const key in paramsObj) {
            if (paramsObj.hasOwnProperty(key)) {
                if (nowIndex == 1) {
                    resParams += key + "=" + encodeURIComponent(paramsObj[key]);
                }
                else {
                    resParams += "&" + key + "=" + encodeURIComponent(paramsObj[key]);
                }
                nowIndex += 1;
            }
        }
        Logger.log("setParams==============", paramsObj, resParams);
        return resParams;
    }


    public setResponseType(responseType: XMLHttpRequestResponseType) {
        this.responseType = responseType;
    }

    public setContentType(value: string) {
        this.hadSetContentType = true;
        this.contentType = value;
        // this.xhr.setRequestHeader("content-type", value)
    }

    public setRequestHeader(key: string, value: string) {
        this.myRequestHeader.set(key, value)
    }

    public resetRequestHeader() {
        this.myRequestHeader.clear();
    }

    public requestByForm(url: string, callback: Function, timeOut: number = 10 * 1000) {
        let xhr: XMLHttpRequest = this.xhr;
        xhr.responseType = this.responseType;
        xhr.timeout = timeOut;
        xhr.onreadystatechange = () => {
            // Logger.info("http request======onreadystatechange", xhr.readyState, xhr.status);
            if (xhr.readyState == 4 && xhr.status == 200) {
                // Logger.info("http request======onreadystatechange222", xhr.responseText);
                // Logger.info("http request======onreadystatechange333", xhr.response);
                let response = xhr.response;
                // Logger.info("http request======response========", response);
                try {
                    if (callback) {
                        callback(true, response);
                        callback = null;
                    }
                } catch (error) {
                    if (callback) {
                        callback(false);
                        callback = null;
                    }
                }
            } else if (xhr.readyState == 4 && xhr.status == 301) {//域名转移
                this.requestByForm(xhr.getResponseHeader("Location"), callback);
            }
            else if (xhr.readyState == 4 && xhr.status == 404) {
                if (callback) {
                    callback(false);
                    callback = null;
                }
            }
            else {
                if (xhr.readyState == 4) {
                    if (callback) {
                        callback(false);
                        callback = null;
                    }
                }
            }
        };
        xhr.onprogress = () => {
        }
        xhr.onerror = () => {
            Logger.warn("http request======error========", url);
            if (callback) {
                callback(false);
                callback = null;
            }
        }
        xhr.ontimeout = () => {
            Logger.warn("http request======ontimeout========", url);
            if (callback) {
                callback(false);
                callback = null;
            }
        }
        // Logger.info("http request======url========", url);
        xhr.open(this.methodType, url, true);
        if (!this.hadSetContentType) {
            xhr.setRequestHeader("content-type", "text/plain;charset=UTF-8")
        } else {
            xhr.setRequestHeader("content-type", this.contentType)
        }
        this.myRequestHeader.forEach((value, key) => {
            xhr.setRequestHeader(key, value)
        });
        xhr.send();
        this.resetRequestHeader()
    }

    public requestByBody(url: string, callback: Function, params: any = null, timeOut: number = 10 * 1000) {
        let xhr: XMLHttpRequest = this.xhr;
        xhr.responseType = this.responseType;
        xhr.timeout = timeOut;
        xhr.onreadystatechange = () => {
            if (xhr.readyState == 4 && xhr.status == 200) {
                let response = xhr.response;
                // Logger.info("http request======response========", response);
                try {
                    if (callback) {
                        callback(true, response);
                        callback = null;
                    }
                } catch (error) {
                    if (callback) {
                        callback(false);
                        callback = null;
                    }
                }
            } else if (xhr.readyState == 4 && xhr.status == 301) {//域名转移
                this.requestByBody(xhr.getResponseHeader("Location"), callback);
            }
            else if (xhr.readyState == 4 && xhr.status == 404) {
                if (callback) {
                    callback(false);
                    callback = null;
                }
            }
            else {
                if (xhr.readyState == 4) {
                    if (callback) {
                        callback(false);
                        callback = null;
                    }
                }
            }
        };
        xhr.onprogress = () => {
        }
        xhr.onerror = () => {
            Logger.warn("http request======error========", url);
            if (callback) {
                callback(false);
                callback = null;
            }
        }
        xhr.ontimeout = () => {
            Logger.warn("http request======ontimeout========", url);
            if (callback) {
                callback(false);
                callback = null;
            }
        }
        Logger.info("http request======url========", url);
        Logger.info("http request======params========", params);
        xhr.open(this.methodType, url, true);
        if (!this.hadSetContentType) {
            xhr.setRequestHeader("content-type", "text/plain;charset=UTF-8")
        } else {
            xhr.setRequestHeader("content-type", this.contentType)
        }
        this.myRequestHeader.forEach((value, key) => {
            xhr.setRequestHeader(key, value)
        });
        xhr.send(params);
        this.resetRequestHeader()
    }
}
